package cn.ilikes.tools.nosql.jpa.clients.handers.hbases;

import java.lang.reflect.Field;
import java.math.BigDecimal;

import org.apache.hadoop.hbase.util.Bytes;
import org.slf4j.Logger;

import cn.ilikes.tools.logs.Loggerfactory;
import cn.ilikes.tools.nosql.jpa.JPASQLRunTimeException;
import cn.ilikes.tools.nosql.jpa.unitls.PropertyAccessException;

public final class HBaseUtils {
	/** the log used by this class. */
	private static Logger logger = Loggerfactory.instance(HBaseUtils.class);

	public static byte[] getObjectToByte(Object from, Field field) {
		Object oj = getObject(from, field);
		return HBaseUtils.getBytes(oj);
	}

	public static byte[] getBytes(Object o) {

		return getBytes(o, o.getClass());

	}

	public static byte[] putToPutByte(Object from, Field field) {
		Object oj = getObject(from, field);
		Class<?> clazz = oj.getClass();
		return putToByte(oj, clazz);
	}

	public static byte[] putToPutByte(Object key) {

		return putToByte(key, key.getClass());
	}

	private static byte[] putToByte(Object oj, Class<?> clazz) {
		if (clazz.isAssignableFrom(String.class)) {
			return Bytes.toBytes((String) oj);
		} else if (clazz.equals(int.class) || clazz.isAssignableFrom(Integer.class)) {
			return Bytes.toBytes(oj.toString());
		} else if (clazz.equals(long.class) || clazz.isAssignableFrom(Long.class)) {
			return Bytes.toBytes(oj.toString());
		} else if (clazz.equals(double.class) || clazz.isAssignableFrom(Double.class)) {
			return Bytes.toBytes(oj.toString());
		} else if (clazz.equals(float.class) || clazz.isAssignableFrom(Float.class)) {
			return Bytes.toBytes(oj.toString());
		} else if (clazz.equals(short.class) || clazz.isAssignableFrom(Short.class)) {
			return Bytes.toBytes(oj.toString());
		} else if (clazz.equals(BigDecimal.class)) {
			return Bytes.toBytes(oj.toString());
		} else {
			throw new JPASQLRunTimeException(" clazz  " + clazz + " to byte[]  is error ! ");
		}
	}

	public static Object getObject(Object from, Field field) {
		if (!field.isAccessible())
			field.setAccessible(true);
		try {
			if (from == null || field == null) {
				throw new PropertyAccessException(" form  is " + from + " or  field : " + field + " not get field value from from Object");
			}
			return field.get(from);
		} catch (IllegalArgumentException iarg) {
			throw new PropertyAccessException(iarg);
		} catch (IllegalAccessException iacc) {
			throw new PropertyAccessException(iacc);
		}
	}

	//=============================================================================================//

	public static Object getByteTosObject(byte[] value, Class clazz) {
		if (/* isId || */clazz.isAssignableFrom(String.class)) {
			return Bytes.toString(value);
		} else if (clazz.equals(int.class) || clazz.isAssignableFrom(Integer.class)) {
			return Bytes.toInt(value);
		} else if (clazz.equals(long.class) || clazz.isAssignableFrom(Long.class)) {
			return Bytes.toLong(value);
		} else if (clazz.equals(boolean.class) || clazz.isAssignableFrom(Boolean.class)) {
			return Bytes.toBoolean(value);
		} else if (clazz.equals(double.class) || clazz.isAssignableFrom(Double.class)) {
			return Bytes.toDouble(value);
		}
		// else if (clazz.isAssignableFrom(java.util.UUID.class))
		// {
		// return Bytes.toBytes(value.toString());
		// }
		else if (clazz.equals(float.class) || clazz.isAssignableFrom(Float.class)) {
			return Bytes.toFloat(value);
		} else if (clazz.equals(short.class) || clazz.isAssignableFrom(Short.class)) {
			return Bytes.toShort(value);
		} else if (clazz.equals(BigDecimal.class)) {
			return Bytes.toBigDecimal(value);
		} else {
			throw new JPASQLRunTimeException(" clazz  " + clazz + " to byte[]  is error ! ");
		}
	}

	public static Object getPutByteTosObject(byte[] value, Field field) {
		String v = new String(value);
		Class<?> clazz = field.getType();
		if (clazz.isAssignableFrom(String.class)) {
			return Bytes.toString(value);
		} else if (clazz.equals(int.class) || clazz.isAssignableFrom(Integer.class)) {
			return Integer.valueOf(v);
		} else if (clazz.equals(long.class) || clazz.isAssignableFrom(Long.class)) {
			return Long.valueOf(v);
		} else if (clazz.equals(boolean.class) || clazz.isAssignableFrom(Boolean.class)) {
			return Boolean.valueOf(v);
		} else if (clazz.equals(double.class) || clazz.isAssignableFrom(Double.class)) {
			return Double.valueOf(v);
		}
		// else if (clazz.isAssignableFrom(java.util.UUID.class))
		// {
		// return Bytes.toBytes(value.toString());
		// }
		else if (clazz.equals(float.class) || clazz.isAssignableFrom(Float.class)) {
			return Float.valueOf(v);
		} else if (clazz.equals(short.class) || clazz.isAssignableFrom(Short.class)) {
			return Short.valueOf(v);
		} else {
			throw new JPASQLRunTimeException(" clazz  " + clazz + " to byte[]  is error ! ");
		}

	}

	public static Object getByteTosObject(byte[] value, Field field) {
		Class<?> clazz = field.getType();
		return getByteTosObject(value, clazz);
	}

	private static byte[] getBytes(Object value, Class<?> clazz) {
		if (/* isId || */clazz.isAssignableFrom(String.class)) {
			return Bytes.toBytes(value.toString());
		} else if (clazz.equals(int.class) || clazz.isAssignableFrom(Integer.class)) {
			return Bytes.toBytes(Integer.parseInt(value.toString()));
		} else if (clazz.equals(long.class) || clazz.isAssignableFrom(Long.class)) {
			return Bytes.toBytes(Long.parseLong(value.toString()));
		} else if (clazz.equals(boolean.class) || clazz.isAssignableFrom(Boolean.class)) {
			return Bytes.toBytes(Boolean.valueOf(value.toString()));
		} else if (clazz.equals(double.class) || clazz.isAssignableFrom(Double.class)) {
			return Bytes.toBytes(Double.valueOf(value.toString()));
		}
		// else if (clazz.isAssignableFrom(java.util.UUID.class))
		// {
		// return Bytes.toBytes(value.toString());
		// }
		else if (clazz.equals(float.class) || clazz.isAssignableFrom(Float.class)) {
			return Bytes.toBytes(Float.valueOf(value.toString()));
		} else if (clazz.equals(short.class) || clazz.isAssignableFrom(Short.class)) {
			return Bytes.toBytes(Short.valueOf(value.toString()));
		} else if (clazz.equals(BigDecimal.class)) {
			return Bytes.toBytes(BigDecimal.valueOf(new Long(value.toString())));
		} else {
			throw new JPASQLRunTimeException(" clazz  " + clazz + " to byte[]  is error ! ");
			//			if (value.getClass().isAssignableFrom(String.class)) {
			//				value = PropertyAccessorFactory.getPropertyAccessor(clazz).fromString(clazz, value.toString());
			//			}
			//			return PropertyAccessorFactory.getPropertyAccessor(clazz).toBytes(value);
		}
	}

}